import { BaseGraph } from 'pml-graph'
/**
 * 特定业务定制类
 */
 import itemMeta from '@/graph/item-box-config.js'
class GraphApi extends BaseGraph {
    constructor() {
        super()
    }
    init(graphContainer, enabled) {
        super.initGraph(graphContainer, enabled);
        // keep connected when mouse drag move
        this.graph.setDisconnectOnMove(false)
        // 定制锚点图标图标及大小设定,使用时可以放开
        // mxConstraintHandler.prototype.pointImage = new mxImage(mxClient.imageBasePath + '/close.gif', 5, 5);
        this.graph.foldingEnabled = false;
        //this.graph.setCellsLocked(true);
        const createSvgImage = function(w, h, data, coordWidth, coordHeight)
        {
            var tmp = unescape(encodeURIComponent(
                '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">' +
                '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="' + w + 'px" height="' + h + 'px" ' +
                ((coordWidth != null && coordHeight != null) ? 'viewBox="0 0 ' + coordWidth + ' ' + coordHeight + '" ' : '') +
                'version="1.1">' + data + '</svg>'));
        
            return new mxImage('data:image/svg+xml;base64,' + ((window.btoa) ? btoa(tmp) : Base64.encode(tmp, true)), w, h)
        };
        let handleImage = createSvgImage(18, 18, '<circle cx="9" cy="9" r="5" stroke="#fff" fill="#29b6f2" stroke-width="1"/>');
        let fixedHandleImage = createSvgImage(18, 18, '<circle cx="9" cy="9" r="5" stroke="#fff" fill="#29b6f2" stroke-width="1"/><path d="m 7 7 L 11 11 M 7 11 L 11 7" stroke="#fff"/>');
        let terminalHandleImage = createSvgImage(18, 18, '<circle cx="9" cy="9" r="5" stroke="#fff" fill="#29b6f2" stroke-width="1"/><circle cx="9" cy="9" r="2" stroke="#fff" fill="transparent"/>');

        mxEdgeHandler.prototype.createHandleShape = function(index, virtual)
        {
            var source = index != null && index == 0;
            var terminalState = this.state.getVisibleTerminalState(source);
            var c = (index != null && (index == 0 || index >= this.state.absolutePoints.length - 1 ||
                (this.constructor == mxElbowEdgeHandler && index == 2))) ?
                this.graph.getConnectionConstraint(this.state, terminalState, source) : null;
            var pt = (c != null) ? this.graph.getConnectionPoint(this.state.getVisibleTerminalState(source), c) : null;

            var img = (pt != null) ? fixedHandleImage : ((c != null && terminalState != null) ?
            terminalHandleImage : handleImage);
            ``
            if (img != null)
            {
                var shape = new mxImageShape(new mxRectangle(0, 0, img.width, img.height), img.src);
                
                // Allows HTML rendering of the images
                shape.preserveImageAspect = false;
    
                return shape;
            }
            else
            {
                var s = mxConstants.HANDLE_SIZE;
                
                if (this.preferHtml)
                {
                    s -= 1;
                }
                return new mxRectangleShape(new mxRectangle(0, 0, s, s), mxConstants.HANDLE_FILLCOLOR, mxConstants.HANDLE_STROKECOLOR);
            }
        };
        var vertexHandlerCreateSizerShape = mxVertexHandler.prototype.createSizerShape;
        mxVertexHandler.prototype.createSizerShape = function(bounds, index, fillColor)
        {
            if (index !== mxEvent.LABEL_HANDLE && index !== mxEvent.ROTATION_HANDLE) {
                this.handleImage =  handleImage;
            }
            
            return vertexHandlerCreateSizerShape.apply(this, arguments);
        };
                
        let style = new Object();
        style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_SWIMLANE;
        style[mxConstants.STYLE_FONTCOLOR] = '#FFFFFF';
        style[mxConstants.STYLE_HORIZONTAL] = true;
        style[mxConstants.STYLE_FILLCOLOR] = '#045D8A'; 
        style['rounded'] = 1;
        //stylex[mxConstants.STYLE_SWIMLANE_FILLCOLOR] = "#045D8A"
        style[mxConstants.STYLE_STROKECOLOR] = '#239AF7';
        style[mxConstants.STYLE_STROKEWIDTH] = 2;
        style[mxConstants.STYLE_STARTSIZE] = 40;
        style[mxConstants.STYLE_FILL_OPACITY] = 70
        this.graph.getStylesheet().putCellStyle("swimlane", style);
       
        this.registerImage();
        this.customGraphEvent();
        this.graph.zoomTo(1);
        this.graph.center();
    }

    update (shapeEle) {
        let itemMetaDataStr = shapeEle.getAttribute('objData');
        let itemMetaData = JSON.parse(itemMetaDataStr);
        var funct = (graph, evt, cell, x, y) => {
            if (!graph.isEnabled()) {
                return;
            }
            var businessData = {
                type: itemMetaData.type,
                name: itemMetaData.value
            };
            var parent = graph.getDefaultParent();
            var model = this.model = graph.getModel();
            model.beginUpdate();
            var v1 = null;
            if (cell && cell.type === "cloud") {
                let rObj = null;
                let xx =0, yy =0;
                const findP = (parent) =>{
                    if (parent.parent ) findP(parent.parent);
                        if (parent.type==='cloud') {
                            xx += parent.geometry.x;
                            yy += parent.geometry.y;
                            
                            if ( parent.mxObjectId === cell.mxObjectId) {
                                rObj = parent;
                            }
                    }
                    return rObj
                }
                parent = findP(cell);
                v1 = graph.insertVertex(parent, null, itemMetaData.value, x - xx, y - yy, itemMetaData.width, itemMetaData.height, itemMetaData.style);
            } else if (itemMetaData.sharp == "cloud") {
                v1 = graph.insertVertex(parent, null, itemMetaData.value, x, y, itemMetaData.width, itemMetaData.height, itemMetaData.style);

                if (v1 != null) {
                   //this.addSubProcessOverlay(v1);
                }
            } else {
                v1 = graph.insertVertex(parent, null, itemMetaData.value, x, y, itemMetaData.width, itemMetaData.height, itemMetaData.style);
            }
            businessData.id = v1.id;
            v1.type = itemMetaData.type;
            this.setObjectData(v1.id, JSON.stringify(businessData));
            model.endUpdate();
            graph.setSelectionCell(v1);
        };
        var ds = mxUtils.makeDraggable(shapeEle, this.graph, funct);
        ds.setGuidesEnabled(true);
    }
    setXmlValue (xml) {
        super.setXmlValue(xml);
        this.addCellOverlays();
    }
    addCellOverlays(){
        let cells = this.getNodes();
        for (let cell of cells) {
            if (cell.type == 'cloud'){
                this.addCloudOverlay(cell);
            }
        }
    }
    addCloudOverlay(cell){
        let graph = this.graph;
        graph.removeCellOverlays(cell);
        // Creates a new overlay with an image
        var overlay = null;
        if (cell.type == "cloud") {
            let businessData = JSON.parse(cell.businessData || '{}')
            if (businessData.cloudType === "aliyun") {
                overlay = new mxCellOverlay(
                    new mxImage('./img/graph/aliyun.png', 100, 30),
                    null, "center", "top", new mxPoint(0, 20), "pointer");
            } else if (businessData.cloudType === "openstack") {
                overlay = new mxCellOverlay(
                    new mxImage('./img/graph/openstack.png', 100, 30),
                    null, "center", "top", new mxPoint(0, 18), "pointer");
            } else if (businessData.cloudType === "huawei") {
                overlay = new mxCellOverlay(
                    new mxImage('./img/graph/huawei.png', 100, 35),
                    null, "center", "top", new mxPoint(0, 20), "pointer");
            } else if (businessData.cloudType == "tencent") {
                overlay = new mxCellOverlay(
                    new mxImage('./img/graph/tencent.png', 100, 30),
                    null, "center", "top", new mxPoint(0, 20), "pointer");
            }
        }
        // Sets the overlay for the cell in the graph
        overlay && graph.addCellOverlay(cell, overlay);
    }
    registerImage(){
        // let style = new Object();
        // style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_IMAGE;
        // style[mxConstants.STYLE_PERIMETER] = mxPerimeter.RectanglePerimeter;
        // style[mxConstants.STYLE_IMAGE] = "img/graph/vpc.svg";
        // style[mxConstants.STYLE_FONTCOLOR] = '#FFFFFF';
        // style[mxConstants.STYLE_VERTICAL_ALIGN] = 'bottom';
        // style[mxConstants.STYLE_SPACING] = '-16';
        // this.graph.getStylesheet().putCellStyle("vpc", style);

        // style = mxUtils.clone(style);
        // style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_IMAGE;
        // style[mxConstants.STYLE_PERIMETER] = mxPerimeter.RectanglePerimeter;
        // style[mxConstants.STYLE_IMAGE] = "img/graph/pcn.svg";
        // style[mxConstants.STYLE_FONTCOLOR] = '#FFFFFF';
        // style[mxConstants.STYLE_VERTICAL_ALIGN] = 'bottom';
        // style[mxConstants.STYLE_SPACING] = '-16';
        // this.graph.getStylesheet().putCellStyle("pcn", style);

        for (let item of itemMeta) {
            if (item.type == "cloud") continue;
            let style = new Object();
            style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_IMAGE;
            style[mxConstants.STYLE_PERIMETER] = mxPerimeter.RectanglePerimeter;
            style[mxConstants.STYLE_IMAGE] = item.icon;
            style[mxConstants.STYLE_FONTCOLOR] = '#FFFFFF';
            style[mxConstants.STYLE_VERTICAL_ALIGN] = 'bottom';
            style[mxConstants.STYLE_SPACING] = '-16';
            this.graph.getStylesheet().putCellStyle(item.style, style);
        }
    }
    customGraphEvent() {
        let graph = this.graph;
        // graph.model.addListener(mxEvent.CHANGE, function(sender, evt) {
        //     /**
        //      * 画图任何变动，增加图元、移动图元、连线等，都会触发
        //      */
        //     console.log("change")
        // });

        graph.addListener(mxEvent.REFRESH, function() {
            /**
             *  元数据变化时，点击确定后触发
             */
            console.log("graph is refresh")
        })

        // graph.addListener(mxEvent.FOLD_CELLS, (sender, evt) => {
        //     let cells = evt.getProperty("cells");
        //     for (var i = 0; i < cells.length; i++) {
        //         var geo = graph.model.getGeometry(cells[i]);
        //         if (geo.alternateBounds != null) {
        //             if (cells[i].isCollapsed()) {
        //                 geo.width = geo.alternateBounds.width - 450;
        //                 graph.setCellsResizable(false)
        //                 //graph.setCellStyles(mxConstants.STYLE_RESIZABLE, 0, cells)
        //             } else {
        //                 geo.width = geo.alternateBounds.width + 450;
        //                 //graph.setCellStyles(mxConstants.STYLE_RESIZABLE, 1, cells)
        //                 graph.setCellsResizable(true)
        //             }
        //         }
        //     }
        //     mxEvent.consume(evt, true, true)
        // })
        //this.addZoomListener();
    }
    getGraphMeta(){
        let metaData = this.getGraphMetaDataByParent();
        let nodes = metaData.nodes;
        for (let node of nodes) {
            let cell = this.graph.model.getCell(node.id);
            if (cell.type == "cloud") {
                node.nodes = this.getGraphMetaDataByParent(cell).nodes;
                node.edges = this.getGraphMetaDataByParent(cell).edges;
            }
        }
        return metaData
    }
}

export default GraphApi;